from odoo import models, fields, api, _, Command
from odoo.exceptions import ValidationError
from odoo.tools import float_compare

class StockSubconOutside(models.Model):
    _name = 'stock.subcon.outside'
    _description = 'Stock Subcon Outside'

    def compute_multi_allin(self):
        for rec in self:
            if all([ not float_compare(l.product_qty, l.sub_receipt_qty, precision_rounding=l.product_uom.rounding) for l in rec.line_ids]):
                rec.multi_allin = True
            else:
                rec.multi_allin = False

    name = fields.Char('Name', related='purchase_id.name', store=True)
    purchase_id = fields.Many2one('purchase.order', 'Purchase Order')
    partner_id = fields.Many2one('res.partner', 'Supplier', related='purchase_id.partner_id', store=True)
    date_approve = fields.Datetime('Approve Date', related='purchase_id.date_approve', store=True)
    date_order = fields.Datetime('Order Date', related='purchase_id.date_order', store=True)
    date_planned = fields.Datetime('Planned Date', related='purchase_id.date_planned', store=True)
    picking_type_id = fields.Many2one('stock.picking.type', 'Picking Type', related='purchase_id.picking_type_id',
                                      store=True)
    subcontracting = fields.Boolean('Subcontracting', related='purchase_id.subcontracting', store=True)
    subcon_out = fields.Boolean('Subcon Out', related='purchase_id.subcon_out', store=True)
    subcon_in = fields.Boolean('Subcon In', related='purchase_id.subcon_in', store=True)
    state = fields.Selection(related='purchase_id.state', store=True)
    sb_workflow_state = fields.Selection(related='purchase_id.sb_workflow_state', store=True)
    line_ids = fields.One2many('stock.subcon.outside.line', 'outside_id', 'Stock Subcon Outside Line')
    quality_alert_id = fields.Many2one('quality.alert', 'Quality Alert')
    is_all_outside = fields.Boolean(related='purchase_id.is_all_outside', store=True,default=False, help='包工包料/多工序外发')
    sync_json = fields.Char(string='同步mes的json字串')
    multi_allin = fields.Boolean(string='是否全部入库', compute='compute_multi_allin')

    def action_subcon_out(self):
        for rec in self:
            rec.purchase_id.subcon_out = True
            rec.purchase_id.subcon_out_date = fields.Datetime.now()

    def action_subcon_in(self):
        line_ids = []
        for line in self.line_ids:
            try:
                # 如果pnl数量是小数，提示修正数据后再接收
                int(round(line.product_qty, 2))
            except:
                raise ValidationError('PNL数量不能是小数，请修正后再入库')
            if not float_compare(line.product_qty, line.sub_receipt_qty, precision_rounding=line.product_uom.rounding): continue
            line_ids.append((0, 0, {
                'subcon_line_id': line.id,
                'purchase_order_line_id': line.purchase_line_id.id,
                'service_product_id': line.product_id.id,
                'product_qty': line.product_qty - line.sub_receipt_qty,
                'done_workorder_id': line.stop_workorder_id.id if line.stop_workorder_id else None,
                'workorder_ids': [(4, w.id) for w in line.workorder_ids],
                'qty_received': int(round(line.product_qty - line.sub_receipt_qty, 2)),
            }))

        return {
            'name': _('Receive Delivery'),
            'type': 'ir.actions.act_window',
            'res_model': 'subcontracting.qty.wizard',
            'view_mode': 'form',
            'target': 'new',
            'context': {
                'default_subcon_outside_id': self.id,
                'default_order_id': self.purchase_id.id,
                'default_line_ids': line_ids,
            },
        }


class StockSubconOutsideLine(models.Model):
    _name = 'stock.subcon.outside.line'
    _description = 'Stock Subcon Outside Line'

    @api.depends('purchase_line_id')
    def _compute_workorder_ids(self):
        for rec in self:
            apply_line_id = rec.purchase_line_id.sb_subcontracting_apply_line_id
            if apply_line_id and apply_line_id.start_workorder_id:
                workorder_ids = self.env['mrp.workorder'].sudo().search([('production_id', '=', apply_line_id.start_workorder_id.production_id.id),('step', '>=', apply_line_id.start_workorder_id.step), ('step', '<=', apply_line_id.stop_workorder_id.step)])
                rec.update({
                    'start_workorder_id': apply_line_id.start_workorder_id.id,
                    'stop_workorder_id': apply_line_id.stop_workorder_id.id,
                    'workorder_ids': [(4, w.id) for w in workorder_ids]
                })
            else:
                rec.start_workorder_id = None
                rec.stop_workorder_id = None
                rec.workorder_ids = [Command.clear()]

    outside_id = fields.Many2one('stock.subcon.outside', 'Stock Subcon Outside')
    purchase_id = fields.Many2one('purchase.order', 'Purchase Order', related='outside_id.purchase_id', store=True)
    purchase_line_id = fields.Many2one('purchase.order.line', 'Purchase Order Line')
    product_id = fields.Many2one('product.product', 'Product', related='purchase_line_id.product_id', store=True)
    name = fields.Text('Name', related='purchase_line_id.name', store=True)
    product_qty = fields.Float('Product Qty', related='purchase_line_id.product_qty', store=True)
    qty_received = fields.Float('Product Qty', related='purchase_line_id.qty_received', store=True)
    product_uom = fields.Many2one('uom.uom', 'Product UOM', related='purchase_line_id.product_uom', store=True)
    s_subcontracting_product_id = fields.Many2one('product.product', 'Subcontracting Product',
                                                  related='purchase_line_id.s_subcontracting_product_id', store=True)
    s_specs = fields.Char('Specs', related='purchase_line_id.s_specs', store=True)
    workorder_ids = fields.Many2many('mrp.workorder', string='可选工序', compute='_compute_workorder_ids', store=True)
    start_workorder_id = fields.Many2one('mrp.workorder', string='开始工单', compute='_compute_workorder_ids', store=True)
    stop_workorder_id = fields.Many2one('mrp.workorder', string='结束工单', compute='_compute_workorder_ids', store=True)

    sub_receipt_qty = fields.Float(string='外发已接收数量')
    s_production_id = fields.Many2one('mrp.production', string='工单', related='purchase_line_id.s_production_id',copy=False, readonly=True)

